package org.ghost.wechat.platform.common.mybatis;

import com.baomidou.mybatisplus.toolkit.PluginUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.ghost.wechat.platform.common.constant.SystemConstant;

import java.sql.Connection;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 在分页插件PaginationInterceptor之后
 *
 * @author 01
 */
@Intercepts(@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class}))
public class MaxRowsLimitInterceptor implements Interceptor {
    private final Map<String, Object> properties = new HashMap<String, Object>();

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object target = invocation.getTarget();
        if (target instanceof StatementHandler) {
            StatementHandler statementHandler = (StatementHandler) target;
            MetaObject metaStatementHandler = SystemMetaObject.forObject(statementHandler);
            StatementHandler handler = (StatementHandler) metaStatementHandler.getValue("delegate");
            MappedStatement mappedStatement = (MappedStatement) metaStatementHandler.getValue(PluginUtils.DELEGATE_MAPPEDSTATEMENT);
            BoundSql boundSql = handler.getBoundSql();
            String originSql = boundSql.getSql();

            if (mappedStatement.getSqlCommandType() == SqlCommandType.SELECT) {
                if (!originSql.contains(" LIMIT ") && !originSql.contains(" limit ")) {
                    long limit = MapUtils.getLongValue(properties, "_limit", SystemConstant.DB_QUERY_MAX_ROW);
                    String limitTable = MessageFormat.format(SystemConstant.LIMIT_TABLE_NAME, String.valueOf(System.currentTimeMillis()));
                    String limitSql = "SELECT * FROM (" + originSql + ") AS " + limitTable + " WHERE 1=1 LIMIT " + limit;
                    metaStatementHandler.setValue(PluginUtils.DELEGATE_BOUNDSQL_SQL, limitSql);
                }
                // 将配置属性加入查询参数以使其可以在动态判断语句中使用
            }
//            else if (mappedStatement.getSqlCommandType() == SqlCommandType.INSERT) {
//                Object paramObject = boundSql.getParameterObject();
//                if (paramObject instanceof BaseEntity) {
//
//                }
//
//            } else if (mappedStatement.getSqlCommandType() == SqlCommandType.UPDATE) {
//                Object paramObject = boundSql.getParameterObject();
//                if (paramObject instanceof BaseEntity) {
//
//                }
//            }
        }

        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        if (target instanceof StatementHandler) {
            return Plugin.wrap(target, this);
        }
        return target;
    }

    @Override
    public void setProperties(Properties properties) {
        for (Map.Entry<Object, Object> entry : properties.entrySet()) {
            this.properties.put(entry.getKey().toString(), entry.getValue());
        }
    }
}
